package com.esd.device.utils;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.UnknownHostException;

@Component
public class Modbus_Tcp_Utils {

    private final TcpParameters tcpParameters;

    public Modbus_Tcp_Utils() {
        // 设置主机TCP参数
        this.tcpParameters = new TcpParameters();
        // TCP设置长连接
        this.tcpParameters.setKeepAlive(false);
    }

    public TcpResult readData(
            String ip,
            int port,
            int timeout,
            int slaveId,
            int offset,
            int quantity
    ) throws UnknownHostException, ModbusIOException {
        ModbusMaster master = init(ip, port, timeout);
        if (!master.isConnected()) {
            try {
                master.connect();
            }catch (ModbusIOException e) {
                return TcpResult.error() ;
            }
        }
        try {
            // 读取对应从机的数据，readHoldingRegisters，功能码03
            int[] readHoldingRegisters = master.readHoldingRegisters(slaveId, offset, quantity);
            if (readHoldingRegisters.length < quantity) {
                return TcpResult.miss() ;
            }
            return TcpResult.success(readHoldingRegisters) ;
        }catch (Exception e) {
            return TcpResult.miss() ;
        }finally {
            master.disconnect();
        }
    }

    public ModbusMaster init(
            String ip,
            int port,
            int timeout) throws UnknownHostException {
        // 设置TCP的ip地址
        InetAddress address = InetAddress.getByName(ip); // 写网关的地址
        // TCP参数设置ip地址
        this.tcpParameters.setHost(address);
        this.tcpParameters.setPort(port); // 网关的通讯端口
        this.tcpParameters.setConnectionTimeout(timeout);
        // 创建一个主机
        ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(this.tcpParameters);
        Modbus.setAutoIncrementTransactionId(true);
        return master;
    }

    public TcpResult writeData(
            String ip,
            int port,
            int timeout,
            int slaveId,
            int offset, //寄存器读取开始地址
            int[] datas
    ) throws UnknownHostException, ModbusIOException {
        ModbusMaster master = init(ip, port, timeout);
        if (!master.isConnected()) {
            try {
                master.connect();
            }catch (ModbusIOException e) {
                return TcpResult.error() ;
            }
        }
        try {
            if (datas.length == 1) {
                // 写入对应寄存器的数据，writeSingleRegister，功能码 06
                master.writeSingleRegister(slaveId, offset, datas[0]);
            } else if (datas.length > 1) {
                master.writeMultipleRegisters(slaveId, offset, datas);
            }
            return TcpResult.success(null);
        }catch (ModbusProtocolException | ModbusNumberException e) {
            return TcpResult.miss() ;
        } finally {
            master.disconnect();
        }
    }

    public static void main(String[] args) throws UnknownHostException, ModbusIOException {
        Modbus_Tcp_Utils modbusTcpUtils = new Modbus_Tcp_Utils();
        TcpResult result = modbusTcpUtils.readData(
                "192.168.4.101",
                8886,
                300,
                1,
                0,
                28
        );
        System.out.println(result);
    }
}
